package com.example.gpsparse.service;

import com.example.gpsparse.model.AmapResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.RateLimiter;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * 高德地图API服务
 */
@Service
public class AmapService {

    private static final Logger logger = LoggerFactory.getLogger(AmapService.class);

    @Value("${amap.api.key}")
    private String apiKey;

    @Value("${amap.api.url}")
    private String apiUrl;

    @Value("${amap.api.rate-limit}")
    private double rateLimit;

    @Value("${amap.api.retry.max-attempts}")
    private int maxRetryAttempts;

    @Value("${amap.api.retry.delay}")
    private long retryDelay;

    private RateLimiter rateLimiter;
    private ObjectMapper objectMapper;
    private CloseableHttpClient httpClient;

    @PostConstruct
    public void init() {
        // 初始化限流器
        rateLimiter = RateLimiter.create(rateLimit);
        
        // 初始化JSON解析器
        objectMapper = new ObjectMapper();
        
        // 初始化HTTP客户端
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)
                .setSocketTimeout(5000)
                .setConnectionRequestTimeout(5000)
                .build();
        
        httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();
        
        logger.info("AmapService初始化完成，限流速率: {}次/秒，最大重试次数: {}次", rateLimit, maxRetryAttempts);
    }

    /**
     * 根据经纬度获取地址信息（带重试和限流）
     *
     * @param longitude 经度
     * @param latitude  纬度
     * @return 高德地图API响应
     */
    public AmapResponse getAddressByLocation(double longitude, double latitude) {
        int attempts = 0;
        Exception lastException = null;

        while (attempts < maxRetryAttempts) {
            try {
                // 应用限流
                rateLimiter.acquire();
                
                // 构建请求URL
                URI uri = buildRequestUri(longitude, latitude);
                HttpGet httpGet = new HttpGet(uri);
                
                // 执行请求
                try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                    String responseBody = EntityUtils.toString(response.getEntity());
                    
                    // 解析响应
                    AmapResponse amapResponse = objectMapper.readValue(responseBody, AmapResponse.class);
                    
                    if (amapResponse.isSuccess()) {
                        return amapResponse;
                    } else {
                        logger.warn("高德API请求失败: {}, {}", amapResponse.getInfoCode(), amapResponse.getInfo());
                        // 如果是配额超限或者服务不可用，需要重试
                        if ("10003".equals(amapResponse.getInfoCode()) || "10004".equals(amapResponse.getInfoCode())) {
                            lastException = new IOException("API配额超限或服务不可用: " + amapResponse.getInfo());
                        } else {
                            // 其他错误不需要重试
                            return amapResponse;
                        }
                    }
                }
            } catch (Exception e) {
                lastException = e;
                logger.warn("高德API请求异常，第{}次重试: {}", attempts + 1, e.getMessage());
            }

            attempts++;
            if (attempts < maxRetryAttempts) {
                try {
                    Thread.sleep(retryDelay);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        // 所有重试都失败了，记录错误并返回空响应
        logger.error("高德API请求失败，已重试{}次", attempts, lastException);
        AmapResponse failResponse = new AmapResponse();
        failResponse.setStatus("0");
        failResponse.setInfo(lastException != null ? lastException.getMessage() : "未知错误");
        return failResponse;
    }

    /**
     * 构建请求URI
     *
     * @param longitude 经度
     * @param latitude  纬度
     * @return 请求URI
     * @throws URISyntaxException URI语法异常
     */
    private URI buildRequestUri(double longitude, double latitude) throws URISyntaxException {
        return new URIBuilder(apiUrl)
                .addParameter("key", apiKey)
                .addParameter("location", longitude + "," + latitude)
                .addParameter("extensions", "base")
                .addParameter("output", "JSON")
                .build();
    }
}